/**
 * Copyright (c) 2020 lizebang
 *
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

package plugin

import (
	"fmt"

	"gitee.com/banggua/ggtsync/config"
	"gitee.com/banggua/ggtsync/logger"
	"gitee.com/banggua/ggtsync/plugin/chmod"
	"gitee.com/banggua/ggtsync/plugin/rsync"
)

type Plugin interface {
	Test(map[string]string) error
	Templet() string
	Handle(*config.Project, map[string]string) error
}

type pluginManager struct {
	plugins map[string]Plugin
}

var (
	defaultPluginManager = pluginManager{plugins: make(map[string]Plugin)}
)

func init() {
	defaultPluginManager.plugins[chmod.PluginName] = chmod.DefaultPlugin
	defaultPluginManager.plugins[rsync.PluginName] = rsync.DefaultPlugin
}

func (pm *pluginManager) Handle(project *config.Project, plugins []config.Plugin) error {
	for _, plugin := range plugins {
		if pmPlugin, exist := pm.plugins[plugin.Name]; exist {
			logger.Infof("Start %v", plugin)
			err := pmPlugin.Handle(project, plugin.Args)
			if err != nil {
				return err
			}
			logger.Infof("Finish %v", plugin)
		}
	}
	return nil
}

func (pm *pluginManager) Templet() {
	for _, plugin := range pm.plugins {
		logger.Infof("plugin templet:\n%s", plugin.Templet())
	}
}

func (pm *pluginManager) Test(project *config.Project, plugins []config.Plugin) error {
	for _, plugin := range plugins {
		if pmPlugin, exist := pm.plugins[plugin.Name]; !exist {
			logger.Errorf("project: %s, plugin: %s\n  error: not suppport\n", project.Name, plugin.Name)
			return fmt.Errorf("not suppport plugin %s", plugin.Name)
		} else {
			err := pmPlugin.Test(plugin.Args)
			if err != nil {
				logger.Infof("project: %s, plugin: %s\ntemplet:\n%s\n", project.Name, plugin.Name, pm.plugins[plugin.Name].Templet())
				return err
			}
		}
	}
	return nil
}
